package com.seguriapp.gwt.client;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.seguriapp.entities.MenuLink;

public class MenuPrincipal extends Composite implements MenuPresenter.Display {

  private static final String ESTILO_SELECCIONADO = Recursos.INSTANCE.css().seleccionado();

  /** Representacion de los recursos CSS usados por el menu */
  public interface MenuCss extends CssResource {

    String menuContenedor();

    String menuGrupo();

    String menuCabecera();

    String menuEnlace();

    String seleccionado();
  }

  /** Representacion de los recursos usados por el menu */
  public interface Recursos extends ClientBundle {

    public static final Recursos INSTANCE = GWT.create(Recursos.class);

    @Source("menu.css")
    public MenuCss css();
  }

  private static MenuPrincipalUiBinder uiBinder = GWT.create(MenuPrincipalUiBinder.class);

  interface MenuPrincipalUiBinder extends UiBinder<Widget, MenuPrincipal> {
  }

  public MenuPrincipal() {
    initWidget(uiBinder.createAndBindUi(this));
    horizontalPanel.addStyleName(Recursos.INSTANCE.css().menuContenedor());
  }

  @UiField
  HorizontalPanel horizontalPanel;

  private MenuPresenter presenter;
  private Anchor anchorSeleccionado;
  private List<DisclosurePanel> cabeceras;

  public MenuPrincipal(String firstName) {
    initWidget(uiBinder.createAndBindUi(this));
  }

  public void setDatosMenu(final List<MenuLink> items) {

    horizontalPanel.clear();
    // Aqui se adicionan todos los links del menu.
    HorizontalPanel panelEnlaces = new HorizontalPanel();
    panelEnlaces.addStyleName(Recursos.INSTANCE.css().menuGrupo());
    for (final MenuLink menuLink : items) {
      // Los items con path no nulo pertenecen a la aplicacion anterior.
      final Anchor anchor = new Anchor(SafeHtmlUtils.fromTrustedString(menuLink.getName()));
      anchor.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent e) {
          // Previene que se ejecute un page load en IE.
          e.preventDefault();
          presenter.navegar(menuLink);
        }
      });
      // Mantiene el enlace de menu seleccionado.
      anchor.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent e) {
          Anchor anchor = (Anchor) e.getSource();
          if (anchorSeleccionado != null && anchor != anchorSeleccionado) {
            anchorSeleccionado.removeStyleName(ESTILO_SELECCIONADO);
          }
          anchorSeleccionado = anchor;
          anchorSeleccionado.addStyleName(ESTILO_SELECCIONADO);
        }
      });
      anchor.setStyleName(Recursos.INSTANCE.css().menuEnlace());
      anchor.getElement().setId(menuLink.getPath());
      panelEnlaces.add(anchor);
    }
    horizontalPanel.add(panelEnlaces);
  }

  public void setMenuPresenter(MenuPresenter menuPresenter) {
    this.presenter = menuPresenter;
  }

  public void setItemSeleccionado(String menuId, String idPadre) {
    for (final DisclosurePanel grupoMenu : cabeceras) {
      // buscamos el disclosure panel indicado como padre y lo abrimos
      if (grupoMenu.getHeader().getParent().getElement().getId().equals(idPadre)) {
        grupoMenu.setOpen(true);
      }
      // removemos el estilo seleccionado entre los anchors hijos
      final NodeList<Element> menuLinks = grupoMenu.getContent().getElement().getElementsByTagName("a");
      final int length = menuLinks.getLength();
      for (int i = 0; i < length; i++) {
        final AnchorElement menuLink = (AnchorElement) menuLinks.getItem(i);
        menuLink.removeClassName(ESTILO_SELECCIONADO);
      }
    }
    if (null != anchorSeleccionado) {
      anchorSeleccionado.removeStyleName(ESTILO_SELECCIONADO);
    }
    Document.get().getElementById(menuId).addClassName(ESTILO_SELECCIONADO);
  }

}
